Imports System.Net
Imports System.Net.Sockets

Public Class NetworkHandler

    Private Enum eConnectionState
        CONNECTED
        AUTHED_GG
        AUTHED_LOGIN
    End Enum

    Private _socket As Socket
    Private _sessionManager As SessionManager
    Private _state As eConnectionState

    Public Property Socket() As Socket
        Get
            Return _socket
        End Get
        Set(ByVal value As Socket)
            _socket = value
        End Set
    End Property

    Public Property SessionManager() As SessionManager
        Get
            Return _sessionManager
        End Get
        Set(ByVal value As SessionManager)
            _sessionManager = value
        End Set
    End Property

    Public Sub Handle()
        Try
            Dim byteRecv(2048) As Byte
            Dim recvBytes As Integer
            Dim MaxBufferSize As Long = 2048
            _state = eConnectionState.CONNECTED
            Do
                While _socket.Available() = 0
                    If gEvtStopServer.WaitOne(100, True) = True Then
                        gLog.LogDebug("Stopping Thread...")
                        Exit Sub
                    End If
                End While
                ReDim byteRecv(2048)
                recvBytes = Socket.Receive(byteRecv, SocketFlags.None)
                If recvBytes = 0 Then
                    gLog.LogDebug("closing client handling thread...")
                End If

                Dim pck As AionClientPacket = ProcessMessage(byteRecv, recvBytes)
                pck.Socket = _socket
                gLog.LogDebug("received packet: {0}", pck.ToString)
                If Not pck Is Nothing Then
                    Dim impl As New Threading.Thread(AddressOf pck.RunImpl)
                    impl.Start()
                End If
            Loop
            gLog.LogDebug("closing client handling thread...")
        Catch ex As Exception
            gLog.LogError(ex)
        End Try
    End Sub

    Private Function ProcessMessage(ByVal bytes As Byte(), ByVal received As Integer) As AionClientPacket
        Try
            gLog.LogDebug(PacketFunctions.ByteArrayToHex(bytes, received))
            Dim ms As New IO.MemoryStream(bytes, 0, received)
            Dim br As New IO.BinaryReader(ms)

            Dim acp As AionClientPacket
            Dim header As Packet.eClientOPCodes = CType(br.ReadInt16, Packet.eClientOPCodes)

            Select Case _state
                Case eConnectionState.CONNECTED
                    Select Case header
                        Case Packet.eClientOPCodes.CM_AUTH_GG
                            acp = New CM_AUTH_GG(br)
                            Return acp

                        Case Packet.eClientOPCodes.CM_UPDATE_SESSION
                            acp = New CM_UPDATE_SESSION()
                            Return acp

                        Case Else

                    End Select

                Case eConnectionState.AUTHED_GG
                    Select Case header
                        Case Packet.eClientOPCodes.CM_LOGIN
                            acp = New CM_LOGIN()
                            Return acp

                        Case Else

                    End Select

                Case eConnectionState.AUTHED_LOGIN
                    Select Case header
                        Case Packet.eClientOPCodes.CM_SERVER_LIST
                            acp = New CM_SERVER_LIST()
                            Return acp

                        Case Packet.eClientOPCodes.CM_PLAY
                            acp = New CM_PLAY()
                            Return acp

                        Case Else

                    End Select
            End Select
            Return Nothing
        Catch ex As Exception
            gLog.LogError(ex)
            Return Nothing
        End Try
    End Function

    Private Sub SendData(ByVal data() As Byte)
        Try
            gLog.LogDebug("Sending: {0}", PacketFunctions.ByteArrayToHex(data))
            Socket.Send(data, data.Length, SocketFlags.None)
        Catch ex As Exception
            gLog.LogError(ex)
        End Try
    End Sub
End Class